﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Bam.Lib
{
    /// <summary>
    /// This class keeps track of previous mouse input states to determine
    /// if mouse buttons have just been pressed or released, or other time-
    /// sensitive information.
    /// </summary>
    public class InputManager
    {        
        MouseState oldMouseState;
        MouseState newMouseState;

        KeyboardState oldKeyboardState;
        KeyboardState newKeyboardState;

        /// <summary>
        /// This is the position of the mouse when a left or right click was last
        /// initiated.  This can be used for checking if the mouse was originally
        /// clicked inside a button when it is released, for example.
        /// </summary>
        public Point OriginalPosition;

        /// <summary>
        /// The position of the mouse in the previous frame.  Needed for checking
        /// MouseIn and MouseOut conditions.
        /// </summary>
        public Point PreviousPosition;

        /// <summary>
        /// The current position of the mouse.
        /// </summary>
        public Point MousePosition;

        public bool IsDragging = false;
        public bool DragBegin = false;
        bool hasIssuedDrag = false;

        public InputManager()
        {
            MousePosition = new Point();
            OriginalPosition = new Point();
            PreviousPosition = new Point();
            newMouseState = Mouse.GetState();
            newKeyboardState = Keyboard.GetState();
        }

        public void Update()
        {
            oldKeyboardState = newKeyboardState;
            newKeyboardState = Keyboard.GetState(); 

            oldMouseState = newMouseState;
            newMouseState = Mouse.GetState();
            PreviousPosition.X = MousePosition.X;
            PreviousPosition.Y = MousePosition.Y;
            MousePosition.X = newMouseState.X;
            MousePosition.Y = newMouseState.Y;

            // Detect that a button has just been pressed.
            if (((oldMouseState.LeftButton == ButtonState.Released &&
                newMouseState.LeftButton == ButtonState.Pressed) ||
                (oldMouseState.RightButton == ButtonState.Released &&
                newMouseState.RightButton == ButtonState.Pressed)) &&
                !IsDragging)
            {
                OriginalPosition = new Point(newMouseState.X, newMouseState.Y);
                IsDragging = true;
            }
  
            
            if (IsDragging)
            {
                // Check to enable a Drag Start state.  This only happens for one frame.
                if (!hasIssuedDrag && (MousePosition.X - OriginalPosition.X != 0 || MousePosition.Y - OriginalPosition.Y != 0))
                {
                    DragBegin = true;
                    hasIssuedDrag = true;
                }
                else
                {
                    DragBegin = false;
                }

                IsDragging = !(LeftButtonReleased || RightButtonReleased); // End dragging on click release
            }
            else
            {
                DragBegin = false;
                hasIssuedDrag = false;
            }
        }

        /// <summary>
        /// Is true if left click has just switched from a pressed state to a released state.
        /// </summary>
        public bool LeftButtonReleased
        {
            get
            {
                return oldMouseState.LeftButton == ButtonState.Pressed && newMouseState.LeftButton == ButtonState.Released;
            }
        }

        /// <summary>
        /// Is true if right click has just switched from a pressed state to a released state.
        /// </summary>
        public bool RightButtonReleased
        {
            get
            {
                return oldMouseState.RightButton == ButtonState.Pressed && newMouseState.RightButton == ButtonState.Released;
            }
        }

        /// <summary>
        /// Is true if the left button has just changed from a released state to a pressed state.
        /// </summary>
        public bool LeftButtonPressed
        {
            get
            {
                return oldMouseState.LeftButton == ButtonState.Released && newMouseState.LeftButton == ButtonState.Pressed;
            }
        }

        /// <summary>
        /// Is true if the right button has just changed from a released state to a pressed state.
        /// </summary>
        public bool RightButtonPressed
        {
            get
            {
                return oldMouseState.RightButton == ButtonState.Released && newMouseState.RightButton == ButtonState.Pressed;
            }
        }
        public bool isKeyDown(Keys k)
        {
            return newKeyboardState.IsKeyDown(k);    
        }
        // tests if the key was pressed but not held
        public bool isKeyPressed(Keys k)
        {
            return (oldKeyboardState.IsKeyUp(k) && newKeyboardState.IsKeyDown(k));
        }
        public void Reset()
        {

            oldMouseState = newMouseState;
            OriginalPosition = MousePosition;
            PreviousPosition = MousePosition;
            DragBegin = false;
            hasIssuedDrag = false;
            IsDragging = false;
        }
    }
}
